package com.platform.filter;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.alibaba.fastjson.JSON;
import com.platform.base.Constants;
import com.platform.config.IgnoreTokenConfig;
import com.platform.context.SSOUserContext;
import com.platform.entity.SSOUserModel;
import com.platform.ext.cache.utils.RedisCache;
import com.platform.utils.SpringContextUtil;
import com.platform.utils.TokenManager;

import cn.hutool.core.util.StrUtil;
import lombok.extern.log4j.Log4j;

/**
 * @ClassName: ValidateFilter
 * @Description: 验证过滤类
 * @date: 2022年10月30日 下午3:02:33
 * @author: <a href="mailto:15909910367@163.com">吴先生</a>
 * @Copyright: 2022 吴元森.
 */
@Log4j 
public class ValidateFilter implements Filter {
	
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		String httpMethod = request.getMethod();
		HttpServletResponse response = (HttpServletResponse) servletResponse;
		String allowOrigin = request.getHeader("Origin");
		String allowHeader = request.getHeader("Access-Control-Request-Headers");
		response.setHeader("Access-Control-Allow-Origin", allowOrigin);
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Allow-Methods", "OPTIONS, POST, PUT, GET, DELETE");
		response.setHeader("Access-Control-Allow-Headers", allowHeader);
		
		String token = request.getHeader(Constants.ACCESS_TOKEN);
		if (StringUtils.isBlank(token)) {
            token = request.getParameter(Constants.ACCESS_TOKEN);
        }
		if(!httpMethod.toUpperCase().equals("OPTIONS")) {
			if(IgnoreTokenConfig.isIgnoreToken(getUri(request)) == false) {
				if(StringUtils.isEmpty(token)) {
					response.addHeader("sessionstatus", "timeout");
					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.put("sessionstatus", "timeout");
					resultMap.put("msg", "未登录，无法调用服务");
					resultMap.put("code", 99);
					resultMap.put("success", false);
					writeToResponse(response, resultMap);
					return;
				}
				if(!TokenManager.validateToken(token)) {
					response.addHeader("sessionstatus", "timeout");
					Map<String, Object> resultMap = new HashMap<String, Object>();
					resultMap.put("sessionstatus", "timeout");
					resultMap.put("msg", "无效身份认证，无法调用服务");
					resultMap.put("code", 99);
					resultMap.put("success", false);
					writeToResponse(response, resultMap);
					return;
				}
				RedisCache redis = SpringContextUtil.getBean(RedisCache.class);
				Map<String,Object> obj = redis.getCacheObject("platform:session:aCTh_"+TokenManager.getUserID(token));
				SSOUserModel sso = SSOUserModel.builder()
						.id(obj.get("userid").toString())
						.loginName(obj.get("username").toString())
						.userName(obj.get("realname").toString())
						.org(obj.get("dept").toString())
						.orgId(obj.get("deptCode").toString())
						.premissions(com.platform.utils.StringUtils.StringToList(obj.get("permissions").toString(), ","))
						.build();
		        SSOUserContext.setContext(sso);
			}
		}
		filterChain.doFilter(servletRequest, servletResponse);
	}

	private void writeToResponse(HttpServletResponse response, Object o) {
		OutputStream os = null;
		response.setContentType("application/json;charset=utf-8");
		response.setCharacterEncoding("UTF-8");
		try {
			os = response.getOutputStream();
			String str = JSON.toJSONString(o);
			os.write(str.getBytes("utf-8"));
			os.flush();
			return;
		} catch (IOException e) {
			log.error("ValidateFilter.writeToResponse error", e);
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					log.error("ValidateFilter.writeToResponse close OutputStream error", e);
				}
			}
		}
	}
	
	private String getUri(HttpServletRequest request) {
        String uri = request.getRequestURI();
        uri = StrUtil.subSuf(uri, 4);//路由过来必须保证都是4位
        uri = StrUtil.subSuf(uri, uri.indexOf("/", 1));
        return uri;
    }

}
